import React, {
  Fragment,
  FunctionComponent,
  useEffect,
  lazy,
  Suspense,
} from "react";
import { Spin } from "antd";
import { useDispatch } from "react-redux";
import { getShoppingCart } from "./redux/shoopingCart/shoopingCartSlice";
import { Switch, Route, Redirect } from "react-router-dom";
import { useSelector } from "./redux/hooks";
import {
  HomePage,
  SingInPage,
  RegisterPage,
  DetailPage,
  SearchPage,
  ShoppingCart,
  MenuDetail
} from "./pages";
import "./styles/antd-ui.module.scss";

// 异步加载组件
const PlaceOrder = lazy(() => import("./pages/placeOrder/PlaceOrder"));

// 私有路由组件 --- 购物车组件
interface PrivteProps {
  component: FunctionComponent<any>;
  isLogined: boolean;
  path: string | null;
}
const PrivteRoute: React.FC<PrivteProps> = (props) => {
  const { component, isLogined, path } = props;
  // 如果该组件有授权，那么就应该return组件本身; 如果没有授权，那么则重定向登录页面
  const routeComponent = (props: any) => {
    return isLogined ? (
      React.createElement(component, props)
    ) : (
      <Redirect to="/singIn" />
    );
  };
  // 最后将组件嵌入到路由组件并进行返回
  return <Route render={routeComponent} {...path} />;
};

function App() {
  const jwt = useSelector((s) => s.user.token);
  const dispatch = useDispatch();
  useEffect(() => {
    if (jwt) {
      dispatch(getShoppingCart(jwt));
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [jwt]);
  return (
    <Fragment>
      {/* // Switch匹配单一路径
      优先匹配最前面的路径并对之后的路径做短路处理，即不再渲染后面的路由内容 */}
      <Switch>
        <Route exact={true} path="/" component={HomePage} />
        <Route path="/detail/:id" component={DetailPage} />
        <Route path="/singIn" component={SingInPage} />
        <Route path="/register" component={RegisterPage} />
        <Route path="/search/:keyword?" component={SearchPage} />
        <Route exact path="/menuDetail/:params/:name/:age" component={MenuDetail}></Route>
        <PrivteRoute
          isLogined={!!jwt}
          path="/shoppingcart"
          component={ShoppingCart}
        />
        <Suspense
          fallback={
            <Spin
              tip="Loading..."
              style={{
                marginTop: 200,
                marginLeft: "auto",
                marginBottom: 200,
                marginRight: "auto",
                width: "100%",
              }}
            />
          }
        >
          <PrivteRoute
            path="/placeOrder"
            isLogined={!!jwt}
            component={PlaceOrder}
          />
        </Suspense>
        {/* 设置404页面 应对路径不存在 */}
        <Route path="*" render={() => <h2>404 not found</h2>} />
        {/* Redirect用于当前面的路由都不匹配的时候，重定向到指定的路由组件 */}
        <Redirect to="/" />
      </Switch>
    </Fragment>
  );
}

export default App;
